////////////////////////////////////////////////
// MACHINE GENERATED, PLEASE DONOT MODIFY!    //
////////////////////////////////////////////////

#pragma once

#include "../../plugin/base/module_frame.hh"
#include "../../plugin/base/framework.hh"
#include "../../plugin/protocol/protocol_header.hh"
#include "../../plugin/base/rpc_base.hh"
#include "../../plugin/base/entity.hh"
#include "../../corelib/object_pool.hpp"
#include "rpc_interface_generated.hh"
#include "rpc_generated.hh"

enum class ProxyType {
    PROXYTYPE_PATH = 1,
    PROXYTYPE_SITE,
    PROXYTYPE_ENTITY,
};

RPCSkeleton* skeleton_ = nullptr;

void RPCSkeleton::install() {
    if (!skeleton_) {
        skeleton_ = new RPCSkeleton();
    }
}

void RPCSkeleton::uninstall() {
    delete skeleton_;
    skeleton_ = nullptr;
}

RPCSkeleton::RPCSkeleton() {
    RPCRef.registerSkeleton(this);
}

RPCSkeleton::~RPCSkeleton() {
    RPCRef.registerSkeleton(nullptr);
}

static bool callMethod(ProxyType type, std::uint64_t id, std::uint64_t RPCID, const google::protobuf::Message& msg, AckFunction method, RPCTimeoutCB toCB, std::time_t timeout) {
    auto call = kratos::corelib::allocate<RPCCall<AckFunction>>();
    if (!call) {
        return false;
    }
    call->ackMethod = method;
    if (type == ProxyType::PROXYTYPE_PATH) {
        if (!RPCRef.RPCCallByPath(static_cast<PathID>(id), RPCID, msg, call, toCB, timeout)) {
            kratos::corelib::dispose(call);
            return false;
        }
    } else if (type == ProxyType::PROXYTYPE_SITE) {
        if (!RPCRef.RPCCallBySite(kratos::grid::SiteID(id), RPCID, msg, call, toCB, timeout)) {
            kratos::corelib::dispose(call);
            return false;
        }
    } else if (type == ProxyType::PROXYTYPE_ENTITY) {
        if (!RPCRef.RPCCallByEntity(id, RPCID, msg, call, toCB, timeout)) {
            kratos::corelib::dispose(call);
            return false;
        }
    } else {
        kratos::corelib::dispose(call);
        return false;
    }
    return true;
}

#include "lua_bind_rpc_generated.hh"

ISample* Sample_ = nullptr;
ISample1* Sample1_ = nullptr;

static bool ON_SAMPLE_ECHO(PathID pathID, std::uint64_t UUID, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID = 0, std::uint64_t fromPathID = 0);
static void ON_PATH_SAMPLE_ECHO(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char* data, std::size_t size, ProxyType proxyType = ProxyType::PROXYTYPE_PATH, PathID fromPathID = 0, std::uint64_t entityID = 0);
static void ON_SAMPLE_ECHO_ACK(RPCCallBase* callBase, const char* data, std::size_t size);

static bool ON_SAMPLE_ECHO1(PathID pathID, std::uint64_t UUID, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID = 0, std::uint64_t fromPathID = 0);
static void ON_PATH_SAMPLE_ECHO1(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char* data, std::size_t size, ProxyType proxyType = ProxyType::PROXYTYPE_PATH, PathID fromPathID = 0, std::uint64_t entityID = 0);
static void ON_SAMPLE_ECHO1_ACK(RPCCallBase* callBase, const char* data, std::size_t size);


static bool ON_SAMPLE1_ECHO(PathID pathID, std::uint64_t UUID, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID = 0, std::uint64_t fromPathID = 0);
static void ON_PATH_SAMPLE1_ECHO(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char* data, std::size_t size, ProxyType proxyType = ProxyType::PROXYTYPE_PATH, PathID fromPathID = 0, std::uint64_t entityID = 0);
static void ON_SAMPLE1_ECHO_ACK(RPCCallBase* callBase, const char* data, std::size_t size);

static bool ON_SAMPLE1_ECHO1(PathID pathID, std::uint64_t UUID, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID = 0, std::uint64_t fromPathID = 0);
static void ON_PATH_SAMPLE1_ECHO1(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char* data, std::size_t size, ProxyType proxyType = ProxyType::PROXYTYPE_PATH, PathID fromPathID = 0, std::uint64_t entityID = 0);
static void ON_SAMPLE1_ECHO1_ACK(RPCCallBase* callBase, const char* data, std::size_t size);



class RPCInterface_Sample_proxy_impl : public SampleProxy {
	ProxyType proxyType_;
	std::uint64_t id_;

public:
	RPCInterface_Sample_proxy_impl(ProxyType type, std::uint64_t id) {
		proxyType_ = type;
		id_ = id;
	}
	virtual bool echo(const Message& req, AckFunction method = nullptr, RPCTimeoutCB toCB = nullptr, std::time_t timeout = 2000) override {
		return callMethod(proxyType_, id_, RPC_ID_SAMPLE_ECHO,req, method, toCB, timeout);
	}
	virtual bool echo1(const Message& req, AckFunction method = nullptr, RPCTimeoutCB toCB = nullptr, std::time_t timeout = 2000) override {
		return callMethod(proxyType_, id_, RPC_ID_SAMPLE_ECHO1,req, method, toCB, timeout);
	}
};

class RPCInterface_Sample1_proxy_impl : public Sample1Proxy {
	ProxyType proxyType_;
	std::uint64_t id_;

public:
	RPCInterface_Sample1_proxy_impl(ProxyType type, std::uint64_t id) {
		proxyType_ = type;
		id_ = id;
	}
	virtual bool echo(const Message& req, AckFunction method = nullptr, RPCTimeoutCB toCB = nullptr, std::time_t timeout = 2000) override {
		return callMethod(proxyType_, id_, RPC_ID_SAMPLE1_ECHO,req, method, toCB, timeout);
	}
	virtual bool echo1(const Message& req, AckFunction method = nullptr, RPCTimeoutCB toCB = nullptr, std::time_t timeout = 2000) override {
		return callMethod(proxyType_, id_, RPC_ID_SAMPLE1_ECHO1,req, method, toCB, timeout);
	}
};

std::shared_ptr<SampleProxy> RPCSkeleton::Path::getSample(PathID pathID) {
	return std::shared_ptr<SampleProxy>(new RPCInterface_Sample_proxy_impl(ProxyType::PROXYTYPE_PATH,static_cast<std::uint64_t>(pathID)));
}

std::shared_ptr<SampleProxy> RPCSkeleton::Entity::getSample(std::uint64_t entityID) {
	return std::shared_ptr<SampleProxy>(new RPCInterface_Sample_proxy_impl(ProxyType::PROXYTYPE_ENTITY,entityID));
}

std::shared_ptr<Sample1Proxy> RPCSkeleton::Path::getSample1(PathID pathID) {
	return std::shared_ptr<Sample1Proxy>(new RPCInterface_Sample1_proxy_impl(ProxyType::PROXYTYPE_PATH,static_cast<std::uint64_t>(pathID)));
}

std::shared_ptr<Sample1Proxy> RPCSkeleton::Entity::getSample1(std::uint64_t entityID) {
	return std::shared_ptr<Sample1Proxy>(new RPCInterface_Sample1_proxy_impl(ProxyType::PROXYTYPE_ENTITY,entityID));
}

void RPCSkeleton::dispose(std::uint64_t RPCID, RPCCallBase * callBase) {
	kratos::corelib::dispose(dynamic_cast<RPCCall<AckFunction>*>(callBase));
}

void RPCSkeleton::onPathReq(PathID pathID, std::uint64_t RPCID, std::uint64_t UUID, const char * data, std::size_t size) {
	switch (RPCID) {
		case RPC_ID_SAMPLE_ECHO:
			ON_PATH_SAMPLE_ECHO(pathID, UUID, RPCID, data, size);
			break;
		case RPC_ID_SAMPLE_ECHO1:
			ON_PATH_SAMPLE_ECHO1(pathID, UUID, RPCID, data, size);
			break;
		case RPC_ID_SAMPLE1_ECHO:
			ON_PATH_SAMPLE1_ECHO(pathID, UUID, RPCID, data, size);
			break;
		case RPC_ID_SAMPLE1_ECHO1:
			ON_PATH_SAMPLE1_ECHO1(pathID, UUID, RPCID, data, size);
			break;
		default:
			return;
	}
}
void RPCSkeleton::onPathAck(std::uint64_t RPCID, RPCCallBase * callBase, const char * data, std::size_t size) {
	switch (RPCID) {
		case RPC_ID_SAMPLE_ECHO:
			ON_SAMPLE_ECHO_ACK(callBase, data, size);
			break;
		case RPC_ID_SAMPLE_ECHO1:
			ON_SAMPLE_ECHO1_ACK(callBase, data, size);
			break;
		case RPC_ID_SAMPLE1_ECHO:
			ON_SAMPLE1_ECHO_ACK(callBase, data, size);
			break;
		case RPC_ID_SAMPLE1_ECHO1:
			ON_SAMPLE1_ECHO1_ACK(callBase, data, size);
			break;
		default:
			return;
	}
}
void RPCSkeleton::onEntityReq(PathID pathID, PathID fromPathID, std::uint64_t entityID, std::uint64_t RPCID, std::uint64_t UUID, const char * data, std::size_t size) {
	switch (RPCID) {
		case RPC_ID_SAMPLE_ECHO:
			ON_PATH_SAMPLE_ECHO(pathID, UUID, RPCID, data, size, ProxyType::PROXYTYPE_ENTITY, fromPathID, entityID);
			break;
		case RPC_ID_SAMPLE_ECHO1:
			ON_PATH_SAMPLE_ECHO1(pathID, UUID, RPCID, data, size, ProxyType::PROXYTYPE_ENTITY, fromPathID, entityID);
			break;
		case RPC_ID_SAMPLE1_ECHO:
			ON_PATH_SAMPLE1_ECHO(pathID, UUID, RPCID, data, size, ProxyType::PROXYTYPE_ENTITY, fromPathID, entityID);
			break;
		case RPC_ID_SAMPLE1_ECHO1:
			ON_PATH_SAMPLE1_ECHO1(pathID, UUID, RPCID, data, size, ProxyType::PROXYTYPE_ENTITY, fromPathID, entityID);
			break;
		default:
			return;
	}
}

void RPCSkeleton::onEntityAck(std::uint64_t RPCID, RPCCallBase * callBase, const char * data, std::size_t size) {
	onPathAck(RPCID, callBase, data, size);
}

void ON_PATH_SAMPLE_ECHO(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char * data, std::size_t size, ProxyType proxyType, PathID fromPathID, std::uint64_t entityID) {
	auto reqPtr = RPCRef.newPBProtoMessage("DummyReq");
	if (!reqPtr) {
		errorlog << "Message not found 'DummyReq'" << endlog;
		return;
	}
	reqPtr->ParseFromArray(data, size);
	auto& req = *reqPtr;
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		RPCRef.deletePBProtoMessage(reqPtr);
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	if (!ON_SAMPLE_ECHO(pathID, UUID, RPCID, req, ack, entityID)) {
		RPCRef.deletePBProtoMessage(reqPtr);
		return;
	}
	if(proxyType==ProxyType::PROXYTYPE_PATH) {
		sendPathAck(pathID, UUID, RPCID, ack);
	} else {
		sendEntityAck(pathID, fromPathID, UUID, RPCID, ack);
	}
	RPCRef.deletePBProtoMessage(reqPtr);
	RPCRef.deletePBProtoMessage(ackPtr);
}


void ON_PATH_SAMPLE_ECHO1(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char * data, std::size_t size, ProxyType proxyType, PathID fromPathID, std::uint64_t entityID) {
	auto reqPtr = RPCRef.newPBProtoMessage("DummyReq");
	if (!reqPtr) {
		errorlog << "Message not found 'DummyReq'" << endlog;
		return;
	}
	reqPtr->ParseFromArray(data, size);
	auto& req = *reqPtr;
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		RPCRef.deletePBProtoMessage(reqPtr);
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	if (!ON_SAMPLE_ECHO1(pathID, UUID, RPCID, req, ack, entityID)) {
		RPCRef.deletePBProtoMessage(reqPtr);
		return;
	}
	if(proxyType==ProxyType::PROXYTYPE_PATH) {
		sendPathAck(pathID, UUID, RPCID, ack);
	} else {
		sendEntityAck(pathID, fromPathID, UUID, RPCID, ack);
	}
	RPCRef.deletePBProtoMessage(reqPtr);
	RPCRef.deletePBProtoMessage(ackPtr);
}


void ON_PATH_SAMPLE1_ECHO(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char * data, std::size_t size, ProxyType proxyType, PathID fromPathID, std::uint64_t entityID) {
	auto reqPtr = RPCRef.newPBProtoMessage("DummyReq");
	if (!reqPtr) {
		errorlog << "Message not found 'DummyReq'" << endlog;
		return;
	}
	reqPtr->ParseFromArray(data, size);
	auto& req = *reqPtr;
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		RPCRef.deletePBProtoMessage(reqPtr);
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	if (!ON_SAMPLE1_ECHO(pathID, UUID, RPCID, req, ack, entityID)) {
		RPCRef.deletePBProtoMessage(reqPtr);
		return;
	}
	if(proxyType==ProxyType::PROXYTYPE_PATH) {
		sendPathAck(pathID, UUID, RPCID, ack);
	} else {
		sendEntityAck(pathID, fromPathID, UUID, RPCID, ack);
	}
	RPCRef.deletePBProtoMessage(reqPtr);
	RPCRef.deletePBProtoMessage(ackPtr);
}


void ON_PATH_SAMPLE1_ECHO1(PathID pathID, std::uint64_t UUID, std::uint64_t RPCID, const char * data, std::size_t size, ProxyType proxyType, PathID fromPathID, std::uint64_t entityID) {
	auto reqPtr = RPCRef.newPBProtoMessage("DummyReq");
	if (!reqPtr) {
		errorlog << "Message not found 'DummyReq'" << endlog;
		return;
	}
	reqPtr->ParseFromArray(data, size);
	auto& req = *reqPtr;
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		RPCRef.deletePBProtoMessage(reqPtr);
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	if (!ON_SAMPLE1_ECHO1(pathID, UUID, RPCID, req, ack, entityID)) {
		RPCRef.deletePBProtoMessage(reqPtr);
		return;
	}
	if(proxyType==ProxyType::PROXYTYPE_PATH) {
		sendPathAck(pathID, UUID, RPCID, ack);
	} else {
		sendEntityAck(pathID, fromPathID, UUID, RPCID, ack);
	}
	RPCRef.deletePBProtoMessage(reqPtr);
	RPCRef.deletePBProtoMessage(ackPtr);
}


bool ON_SAMPLE_ECHO(PathID pathID, std::uint64_t uuid, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID, std::uint64_t fromPathID) {
	return LuaRPC::luaCallISampleEcho(pathID, fromPathID, entityID, uuid, rpcID, req, ack);
}

bool ON_SAMPLE_ECHO1(PathID pathID, std::uint64_t uuid, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID, std::uint64_t fromPathID) {
	return LuaRPC::luaCallISampleEcho1(pathID, fromPathID, entityID, uuid, rpcID, req, ack);
}

bool ON_SAMPLE1_ECHO(PathID pathID, std::uint64_t uuid, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID, std::uint64_t fromPathID) {
	return LuaRPC::luaCallISample1Echo(pathID, fromPathID, entityID, uuid, rpcID, req, ack);
}

bool ON_SAMPLE1_ECHO1(PathID pathID, std::uint64_t uuid, std::uint64_t rpcID, const Message& req, Message& ack, std::uint64_t entityID, std::uint64_t fromPathID) {
	return LuaRPC::luaCallISample1Echo1(pathID, fromPathID, entityID, uuid, rpcID, req, ack);
}

void ON_SAMPLE_ECHO_ACK(RPCCallBase * callBase, const char * data, std::size_t size) {
	auto call = dynamic_cast<RPCCall<AckFunction>*>(callBase);
	if (!call->ackMethod) {
		return;
	}
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	ack.ParseFromArray(data, size);
	try {
		call->ackMethod(ack);
	} catch (std::exception& e) {
		errorlog << "Exception:" << e.what() << ", when processing result of RPCID:" << callBase->RPCID << endlog;
	}
	RPCRef.deletePBProtoMessage(ackPtr);
}

void ON_SAMPLE_ECHO1_ACK(RPCCallBase * callBase, const char * data, std::size_t size) {
	auto call = dynamic_cast<RPCCall<AckFunction>*>(callBase);
	if (!call->ackMethod) {
		return;
	}
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	ack.ParseFromArray(data, size);
	try {
		call->ackMethod(ack);
	} catch (std::exception& e) {
		errorlog << "Exception:" << e.what() << ", when processing result of RPCID:" << callBase->RPCID << endlog;
	}
	RPCRef.deletePBProtoMessage(ackPtr);
}

void ON_SAMPLE1_ECHO_ACK(RPCCallBase * callBase, const char * data, std::size_t size) {
	auto call = dynamic_cast<RPCCall<AckFunction>*>(callBase);
	if (!call->ackMethod) {
		return;
	}
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	ack.ParseFromArray(data, size);
	try {
		call->ackMethod(ack);
	} catch (std::exception& e) {
		errorlog << "Exception:" << e.what() << ", when processing result of RPCID:" << callBase->RPCID << endlog;
	}
	RPCRef.deletePBProtoMessage(ackPtr);
}

void ON_SAMPLE1_ECHO1_ACK(RPCCallBase * callBase, const char * data, std::size_t size) {
	auto call = dynamic_cast<RPCCall<AckFunction>*>(callBase);
	if (!call->ackMethod) {
		return;
	}
	auto ackPtr = RPCRef.newPBProtoMessage("DummyAck");
	if (!ackPtr) {
		errorlog << "Message not found 'DummyAck'" << endlog;
		return;
	}
	auto& ack = *ackPtr;
	ack.ParseFromArray(data, size);
	try {
		call->ackMethod(ack);
	} catch (std::exception& e) {
		errorlog << "Exception:" << e.what() << ", when processing result of RPCID:" << callBase->RPCID << endlog;
	}
	RPCRef.deletePBProtoMessage(ackPtr);
}

